package rhplus.gestor;

import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;




public class UtensiliosParaDatas {

    public static String devolveDataEmString(final int ano, final int mes, final int dia) {
        // Criar a data a partir dos tres campos acima.
        GregorianCalendar calendario_gregoriano = new GregorianCalendar(ano, mes - 1, dia);
        Date data_de_nascimento = calendario_gregoriano.getTime();

        String date_out;
        SimpleDateFormat date_formatter;

        date_formatter = new SimpleDateFormat("yyyy-MM-dd");
        date_out = date_formatter.format(data_de_nascimento);

        return date_out;
    }

    public static int dateDiff(int data1, int data2) {

        Date diff = new Date();

        /*diff.setTime(Math.abs(data1.getTime() - data2.getTime()));
        long timeDiff = diff.getTime();
        long dias = (long) Math.floor(timeDiff/(1000*60*60*24));
        String result= String.valueOf(dias);
        int resultf=Integer.parseInt(result);
        System.out.println("* "+timeDiff+" "+dias+" "+resultf);
        return  (resultf/365);         */
        
        return (Math.abs((data1) - data2));
    }

    public static String devolveDataActualPorExtenso() {
        // Criar a data a partir dos tres campos acima.
        Date data = new Date();

        String ano, mes, dia, semana;

        SimpleDateFormat date_formatter;

        date_formatter = new SimpleDateFormat("EEEE");
        semana = date_formatter.format(data);

        date_formatter = new SimpleDateFormat("yyyy");
        ano = date_formatter.format(data);

        date_formatter = new SimpleDateFormat("MMMM");
        mes = date_formatter.format(data);

        date_formatter = new SimpleDateFormat("d");
        dia = date_formatter.format(data);

        return semana + ", dia " + dia + " de " + mes + " de " + ano;
    }

    public static String devolveDataEHoraEmString(final int ano, final int mes, final int dia, final int hora, final int minutos) {
        // Criar a data a partir dos tres campos acima.
        GregorianCalendar calendario_gregoriano = new GregorianCalendar(ano, mes - 1, dia, hora, minutos);
        Date data = calendario_gregoriano.getTime();

        String date_out;
        SimpleDateFormat date_formatter;

        date_formatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        date_out = date_formatter.format(data);

        return date_out;
    }

    public static String devolveDataEHoraParaBD(final int ano, final int mes, final int dia, final int hora, final int minutos) {
        // Criar a data a partir dos tres campos acima.
        GregorianCalendar calendario_gregoriano = new GregorianCalendar(ano, mes - 1, dia, hora, minutos);
        Date data = calendario_gregoriano.getTime();

        String date_out;
        SimpleDateFormat date_formatter;

        date_formatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        date_out = date_formatter.format(data);

        return date_out;
    }

    public static String devolveHoraDaData(final Date data) {
        // Criar a data a partir dos tres campos acima.
        String date_out;
        SimpleDateFormat date_formatter;

        date_formatter = new SimpleDateFormat("HH");
        date_out = date_formatter.format(data);

        return date_out + ":00";
    }

    //Devolve a hora da data em Int
    public static int devolveHoraDaDataInt(final Date data) {

        int date_out;
        SimpleDateFormat date_formatter;

        date_formatter = new SimpleDateFormat("HH");
        date_out = Integer.parseInt(date_formatter.format(data));

        return date_out;
    }

    public static String devolveDataEmStringLonga(final int ano, final int mes) {
        // Criar a data a partir dos tres campos acima.
        GregorianCalendar calendario_gregoriano = new GregorianCalendar(ano, mes - 1, 1);
        Date data_de_nascimento = calendario_gregoriano.getTime();

        String date_out;
        SimpleDateFormat date_formatter;

        date_formatter = new SimpleDateFormat("MMMM");
        date_out = date_formatter.format(data_de_nascimento) + " de ";
        date_formatter = new SimpleDateFormat("yyyy");
        date_out += date_formatter.format(data_de_nascimento);

        return date_out;
    }

    public static Date devolveData(final int ano, final int mes, final int dia) {
        // Criar a data a partir dos tres campos acima.
        GregorianCalendar calendario_gregoriano = new GregorianCalendar(ano, mes - 1, dia);
        Date data_de_nascimento = new Date(calendario_gregoriano.getTimeInMillis());

        return data_de_nascimento;
    }

    public static String converteParaString(Date data) {
        String date_out;
        SimpleDateFormat date_formatter;

        date_formatter = new SimpleDateFormat("yyyy-MM-dd");
        date_out = date_formatter.format(data);

        return date_out;
    }

    public static String converteParaStringComMesSeguinte(Date data) {
        String string_data = converteParaString(data);

        int ano = Integer.parseInt(string_data.substring(0, 4));
        int mes = Integer.parseInt(string_data.substring(5, 7));
        int dia = Integer.parseInt(string_data.substring(8, 10));
        ++mes;

        return devolveDataEmString(ano, mes, dia);
    }

    public static String devolveAnoDaData(Date data) {
        String date_out;
        SimpleDateFormat date_formatter;

        date_formatter = new SimpleDateFormat("yyyy");
        date_out = date_formatter.format(data);

        return date_out;
    }

    public static String devolveMesDaData(Date data) {
        String date_out;
        SimpleDateFormat date_formatter;

        date_formatter = new SimpleDateFormat("MM");
        date_out = date_formatter.format(data);

        return date_out;
    }

    public static String devolveDiaDaData(Date data) {
        String date_out;
        SimpleDateFormat date_formatter;

        date_formatter = new SimpleDateFormat("dd");
        date_out = date_formatter.format(data);

        return date_out;
    }

    //Valida datas anteriores à actual
    public static boolean eValida(final int ano, final int mes, final int dia) {
        Calendar calendar = Calendar.getInstance();

        Date d = devolveData(calendar.get(Calendar.YEAR), calendar.get(Calendar.MONTH), calendar.get(Calendar.DAY_OF_MONTH));

        String aux = devolveAnoDaData(d);
        int ano_actual = Integer.parseInt(aux);

        aux = devolveMesDaData(d);
        int mes_actual = Integer.parseInt(aux);

        aux = devolveDiaDaData(d);
        int dia_actual = Integer.parseInt(aux);


        if (ano < 1850 || ano > ano_actual) // se o gajo for um velhadas dá erro
        {
            return false;
        }
        if (mes <= 0 || mes > 12) // se o mês estiver incorrecto
        {
            return false;
        }

        if (ano == ano_actual) { //se o ano for o actual
            if (mes - 1 == mes_actual) { // se o mês for o actual
                if (dia > dia_actual) { //se o dia for maior que o actual dá erro
                    return false;
                } else { // confirma o dia

                    return validaDiaDoMes(ano, mes, dia);

                }
            } else if (mes > mes_actual) { // caso seja um mês
                return false;

                /*}else  if (dia > dia_actual){ //se o dia for maior que o actual dá erro
                return false;*/
            } else { // confirma o dia

                return validaDiaDoMes(ano, mes, dia);

            }
        } else { //caso o ano seja inferior ao ano actual

            return validaDiaDoMes(ano, mes, dia);


        }


    }

    public static boolean eValidaDataRescisao(final int ano, final int mes, final int dia) {

        Date d = agora();

        String aux = devolveAnoDaData(d);
        int ano_actual = Integer.parseInt(aux);

        aux = devolveMesDaData(d);
        int mes_actual = Integer.parseInt(aux);

        aux = devolveDiaDaData(d);
        int dia_actual = Integer.parseInt(aux);


        if (ano < ano_actual) // se o gajo for um velhadas dá erro
        {
            return false;
        }
        if (mes <= 0 || mes > 12) // se o mês estiver incorrecto
        {
            return false;
        }

        if (ano == ano_actual) { //se o ano for o actual
            if (mes == mes_actual) { // se o mês for o actual
                if (dia < dia_actual) { //se o dia for maior que o actual dá erro
                    return false;
                } else { // confirma o dia

                    return validaDiaDoMes(ano, mes, dia);

                }
            } else if (mes > mes_actual) { // caso seja um mês
                return true;

                /*}else  if (dia > dia_actual){ //se o dia for maior que o actual dá erro
                return false;*/
            } else { // confirma o dia

                return validaDiaDoMes(ano, mes, dia);

            }
        } else { //caso o ano seja inferior ao ano actual

            return validaDiaDoMes(ano, mes, dia);


        }


    }

    public static boolean eValidaDataNascimento(final int ano, final int mes, final int dia) {

        Calendar calendar = Calendar.getInstance();

        Date data_nascimento = devolveData(ano, mes, dia);

        Date data_actual = devolveData(calendar.get(Calendar.YEAR), calendar.get(Calendar.MONTH), calendar.get(Calendar.DAY_OF_MONTH));

        data_actual.setMonth(data_actual.getMonth() + 1);

        String aux = devolveAnoDaData(data_actual);
        int ano_actual = Integer.parseInt(aux);

        aux = devolveMesDaData(data_actual);
        int mes_actual = Integer.parseInt(aux);

        aux = devolveDiaDaData(data_actual);
        int dia_actual = Integer.parseInt(aux);

        data_nascimento.setYear(data_nascimento.getYear() + 18);



        if (ano < 1850 || ano > ano_actual) // se o gajo for um velhadas dá erro
        {
            return false;
        }

        //VERIFICA SE A DATA DE ADMISSAO É MAIOR QUE A DATA DE NASCIMENTO
        if (!eMaiorDoQueDataNascimento(data_actual, data_nascimento)) //Se a data de admissão for superior à de nascimento dá erro
        {
            return false;
        }


        if (mes <= 0 || mes > 12) // se o mês estiver incorrecto
        {
            return false;
        }

        if (ano == ano_actual) { //se o ano for o actual
            if (mes - 1 == mes_actual) { // se o mês for o actual
                if (dia > dia_actual) { //se o dia for maior que o actual dá erro
                    return false;
                } else { // confirma o dia

                    return validaDiaDoMes(ano, mes, dia);

                }
            } else if (mes > mes_actual) { // caso seja um mês
                return false;

                /*}else  if (dia > dia_actual){ //se o dia for maior que o actual dá erro
                return false;*/
            } else { // confirma o dia

                return validaDiaDoMes(ano, mes, dia);

            }
        } else { //caso o ano seja inferior ao ano actual

            return validaDiaDoMes(ano, mes, dia);

        }



    }

    public static boolean eValidaDataAdmissao(final int ano, final int mes, final int dia, final Date data_nascimento) {

        if (data_nascimento == null) {
            return false;
        }


        Calendar calendar = Calendar.getInstance();

        Date data_actual = devolveData(calendar.get(Calendar.YEAR), calendar.get(Calendar.MONTH), calendar.get(Calendar.DAY_OF_MONTH));

//System.out.print(data_actual);
//System.out.print(data_nascimento);

        data_nascimento.setYear(data_nascimento.getYear() + 18);

//System.out.println("ano da data de nascimento "+data_nascimento.getYear());

        //data_actual.setMonth(data_actual.getMonth());

        String aux = devolveAnoDaData(data_actual);
        int ano_actual = Integer.parseInt(aux);

        ano_actual++;

        aux = devolveMesDaData(data_actual);
        int mes_actual = Integer.parseInt(aux);

        aux = devolveDiaDaData(data_actual);
        int dia_actual = Integer.parseInt(aux);

        if (dia < 1 || mes < 1) {
            return false;
        }

        //VERIFICA SE A DATA DE ADMISSAO É MAIOR QUE A DATA DE NASCIMENTO
        if (!eMaiorDoQue(devolveData(ano, mes, dia), data_nascimento)) //Se a data de admissão for superior à de nascimento dá erro
        {
            return false;
        }

        if (mes <= 0 || mes > 12 || ano > ano_actual) // se o mês estiver incorrecto
        {
            return false;
        }

        if (ano == ano_actual) { //se o ano for o actual
            if (mes - 1 == mes_actual) { // se o mês for o actual
                if (dia > dia_actual) { //se o dia for maior que o actual dá erro
                    return false;
                } else { // confirma o dia

                    return validaDiaDoMes(ano, mes, dia);

                }
            } else if (mes > mes_actual) { // caso seja um mês
                return false;

                /*}else  if (dia > dia_actual){ //se o dia for maior que o actual dá erro
                return false;*/
            } else { // confirma o dia

                return validaDiaDoMes(ano, mes, dia);

            }
        } else { //caso o ano seja inferior ao ano actual

            return validaDiaDoMes(ano, mes, dia);

        }



    }

    public static boolean eValidaDataContrato(final int ano, final int mes, final int dia, final Date data_admissao, final Date data_nascimento) {

        if (data_nascimento == null || data_admissao == null) {
            return false;
        }
        
        Calendar calendar = Calendar.getInstance();

        Date data_actual = devolveData(calendar.get(Calendar.YEAR), calendar.get(Calendar.MONTH), calendar.get(Calendar.DAY_OF_MONTH));

        data_actual.setMonth(data_actual.getMonth() + 1);//corrige a cena do mes comecar a 0

        if (dia < 1 || mes < 1) {
            return false;
        }


//if ( !eMaiorDoQue(devolveData(ano, mes, dia), data_admissao) || !eMaiorDoQue(devolveData(ano, mes, dia), data_actual )){
       if (!(eMaiorDoQue(devolveData(ano, mes, dia), data_admissao) && !eMaiorDoQue(devolveData(ano, mes, dia), data_actual))) { //Se a data de termino for superior à de nascimento dá erro ou à data de admissao
            return false;
        }



      
        int validade_maxima_contrato = calendar.get(Calendar.YEAR) + 80;


        if (ano > validade_maxima_contrato) {
            return false;
        }
        
        return validaDiaDoMes(ano, mes, dia);



    }

    public static int diasDoMes(final int mes, final int ano) {

        switch (mes) {
            case 4:
            case 6:
            case 9:
            case 11:
                return 30;
            case 2:
                if ((ano % 4 == 0) && ((ano % 100 != 0) || (ano % 400 == 0))) {
                    return 29;
                } else {
                    return 28;
                }

            default: // (1,3,5,6,7,10,12)
                return 31;
        }
    }

    public static boolean eMaiorDoQue(final Date maior, final Date menor) {
        return maior.compareTo(menor) > 0;
    }

    public static boolean eMaiorDoQueDataNascimento(final Date maior, final Date menor) {
        return maior.compareTo(menor) >= 0;
    }

    public static Date agora() {
        return new Date();
    }

    public static Date devolveDataEmDate(final String string_data) {
        //formato string yyyy-MM-dd
        int ano = Integer.parseInt(string_data.substring(0, 4));
        int mes = Integer.parseInt(string_data.substring(5, 7));
        int dia = Integer.parseInt(string_data.substring(8, 10));

        Date data = devolveData(ano, mes, dia);

        return data;
    }

    public static boolean eMaiorDoQue(final String maior, final String menor) {
        Date data_maior = devolveDataEmDate(maior);
        Date data_menor = devolveDataEmDate(menor);

        return data_maior.compareTo(data_menor) > 0;
    }

    public static String diaSeguinte(final String string_data) {
        //formato string YYYY-MM-DD
        int ano = Integer.parseInt(string_data.substring(0, 4));
        int mes = Integer.parseInt(string_data.substring(5, 7));
        int dia = Integer.parseInt(string_data.substring(8, 10));

        int novo_dia = dia;
        int novo_mes = mes;
        int novo_ano = ano;

        if (diasDoMes(mes, ano) == dia) { //se for ultimo dia do mes
            novo_dia = 1;
            if (mes == 12) { //se for ultimo mes do ano
                novo_mes = 1;
                ++novo_ano;
            } else {
                ++novo_mes;
            }
        } else {
            ++novo_dia;
        }

        return devolveDataEmString(novo_ano, novo_mes, novo_dia);
    }

    public static boolean validaDiaDoMes(final int ano, final int mes, final int dia) {

        switch (mes) {
            case 1:
            case 3:
            case 5:
            case 7:
            case 8:
            case 10:
            case 12:
                if (dia < 1 || dia > 31) {
                    return false;
                }
                break;
            case 4:
            case 6:
            case 9:
            case 11:
                if (dia < 1 || dia > 30) {
                    return false;
                }
                break;
            case 2:
                if ((ano % 4 == 0) && ((ano % 100 != 0) || (ano % 400 == 0))) {
                    if (dia < 1 || dia > 29) {
                        return false;
                    }
                    break;
                } else {
                    if (dia < 1 || dia > 28) {
                        return false;
                    }
                    break;
                }
        }

        return true; //não sei se será assim

    }

    public static String formataZerosDaStringData(final String string_data) {
        //formato string YYYY-MM-DD, pode ser YYYY-m-d, etc

        int primeiro_separador = string_data.indexOf("-", 0);
        int segundo_separador = string_data.indexOf("-", primeiro_separador + 1);
        int tamanho = string_data.length();

        if (tamanho > 10) {
            tamanho = string_data.indexOf(" ", segundo_separador + 1);
        }

        int ano = Integer.parseInt(string_data.substring(0, primeiro_separador));
        int mes = Integer.parseInt(string_data.substring(primeiro_separador + 1, segundo_separador));
        int dia = Integer.parseInt(string_data.substring(segundo_separador + 1, tamanho));

//System.out.println("============== primeiro_separador: " + primeiro_separador + ", segundo_separador: " + segundo_separador + ", tamanho: " + tamanho + ", ano: " + ano + ", mes: " + mes + ", dia: " + dia );

        return devolveDataEmString(ano, mes, dia);
    }

    public static boolean eValidaDataNascimentoMembroAgregado(final int ano, final int mes, final int dia) {

        System.out.println("Entrei no valida data nasc agregado");
        Calendar calendar = Calendar.getInstance();

        Date data_nascimento = devolveData(ano, mes, dia);

        Date data_actual = devolveData(calendar.get(Calendar.YEAR), calendar.get(Calendar.MONTH), calendar.get(Calendar.DAY_OF_MONTH));

        int ano_minimo = calendar.get(Calendar.YEAR) - 120;

        if (dia < 1 || mes < 1 || ano < ano_minimo) {
            return false;
        }

        if (!validaDiaDoMes(ano, mes, dia)) {
            return false;
        }

        return eMaiorDoQueDataNascimento(data_actual, data_nascimento);
    }
}
